/*Main entry point for game*/
#include "SimulationManager.h"
#include "3DCamera.h"
#include "glm\glm.hpp"
#include <cstdio>
#include <cmath>

#include "ParticleCollection.h"

#define WINDOW_W 400
#define WINDOW_H 400

//A global simulation manager.
//This takes care of most boiler-plate code.
//If you only want to draw something, you only need to do three things:
//1) Create a display func with the function signerature
//	void funcname()
//2) In main, call 
//	sm.SetCallbackDisplay(funcname)
//  where funcname is the name of your draw function.
//3) In main, after the above function call, call
//	sm.Run();
//  This will start running the simulation.
// 
//  For a list of the callbacks the user can set, look at the "SetCallback..." functions 
//  in the SimulationManager header file.
//  Also, the GetCamera() method will get the camera and allow you to call methods which move
//	around the scene or rotate, etc.
SimulationManager sm(WINDOW_W, WINDOW_H);

ParticleCollection parts;

//Display
//This function will be called as fast as possible, unlike the Update func.
//Only GL display code should be put in this section.  The screen
//is automatically cleared to white in the InitFrames() func, and the 
//glfwSwapBuffers() is called by the default EndFrames() function, so you only
//have to worry about actual drawing here.
void Display() {

	//XXX
	//All drawing code goes here
	//...
	ParticleIter pi = parts.Begin();

	ParticleIter pie = parts.End();
	glPointSize(10.0);

	glColor3f(0.0, 1.0, 0.0);

	/*glBegin(GL_LINES);
		glVertex3fv(&(pi.pos()[0]));
		glVertex3fv(&(++pi).pos()[0]);
	glEnd();*/

	glBegin(GL_POINTS);
	for ( pi = parts.Begin();
		  pi != parts.End();
		  ++pi )
	{
		glVertex3fv(&(pi.pos()[0]));
	}
	glEnd();

	//...
	//XXX
}

//Update
//This function will be called every timestep (ts).  The timestep can be
//set via the SetTimeStep method in SimulationManager. Put all non-drawing code
//here.
void Update(float ts) {
	//XXX
	//All update code goes here
	//...

	//...
	//XXX	
}

void CreateParticles() {
	ParticleDef def;
	def.pos = glm::vec3(0.0, 0.0, 0.0);
	def.mass = 1;

	parts.Insert(def);

	def.pos = glm::vec3(1.0, 0.0, 0.0);
	def.mass = 2;
	parts.Insert(def);
}

int main (int argc, char ** argv ){
	CreateParticles();

	sm.SetCallbackDisplay(Display);
	sm.SetCallbackUpdate(Update);

	//XXX
	//Can initialize the camera and simulator params (callbacks) here
	//...

	//XXX

	//Start simulation.
	sm.Run();
}